﻿using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using DataLayer;
using Moq;
using DataLayer.Entities;
using System.Data.Entity;
using System.Linq;
using DataLayer.Models;
using System.Collections.Generic;

namespace UnitTests
{
    [TestClass]
    public class when_saving_an_exchange_rate
    {
        private CurrencyData _target;
        private Mock<IDatabaseEntities> _databaseEntitiesMock;
        private Mock<IDbSet<ExchangeRate>> _dbSetMock;

        [TestInitialize]
        public void Initialize()
        {
            _databaseEntitiesMock = new Mock<IDatabaseEntities>();
            _dbSetMock = new Mock<IDbSet<ExchangeRate>>();
            _databaseEntitiesMock.Setup(x => x.ExchangeRates)
                .Returns(_dbSetMock.Object);

            _target = new CurrencyData(_databaseEntitiesMock.Object);
        }

        [TestMethod]
        public void inserts_record_when_it_is_new()
        {
            var newExchangeRate = new ExchangeRateModel
            {
                CountryCode = "CAD",
                ExchangeDate = DateTime.Today,
                Rate = 1.0734M
            };

            _dbSetMock.Setup(x => x.Add(It.Is<ExchangeRate>(
                rate => rate.CountryCode == newExchangeRate.CountryCode
                        && rate.ExchangeDate == newExchangeRate.ExchangeDate
                        && rate.Rate == newExchangeRate.Rate)))
                .Verifiable();

            _databaseEntitiesMock.Setup(x => x.SaveChanges())
                .Verifiable();

            _target.SaveExchangeRate(newExchangeRate);

            _databaseEntitiesMock.Verify();
        }

        [TestMethod]
        public void updates_record_when_it_is_not_new()
        {
            var existingExchangeRate = new ExchangeRateModel
            {
                Id = 123,
                CountryCode = "CAD",
                ExchangeDate = DateTime.Today,
                Rate = 1.0734M
            };

            var data = new ExchangeRate
            {
                Id = 123,
                CountryCode = "USD",
                ExchangeDate = DateTime.Today,
                Rate = 1M
            };

            var queryable = new List<ExchangeRate>{data}.AsQueryable();
            _dbSetMock.Setup(x => x.Provider).Returns(queryable.Provider);
            _dbSetMock.Setup(x => x.Expression).Returns(queryable.Expression);
            _dbSetMock.Setup(x => x.ElementType).Returns(queryable.ElementType);
            _dbSetMock.Setup(x => x.GetEnumerator()).Returns(queryable.GetEnumerator());

            _databaseEntitiesMock.Setup(x => x.SaveChanges())
                .Verifiable();

            _target.SaveExchangeRate(existingExchangeRate);

            Assert.AreEqual("CAD", data.CountryCode);
            Assert.AreEqual(1.0734M, data.Rate);

            _databaseEntitiesMock.Verify();
        }
    }
}
